package ru.lukyanets.transmission.client.util;

import org.apache.commons.lang3.LocaleUtils;

import java.util.*;

/**
 * @author slukyanets
 */
public final class LocalizationUtil {

    private static final String LOCALIZATION_BUNDLE_BASE_NAME = "i18n.messages";

    private static final Map<Locale, ResourceBundle> BUNDLES;
    private static final Set<Locale> LOCALES;
    private static Locale locale;

    static {
        Map<Locale, ResourceBundle> availableBundles = new HashMap<>();
        for (Locale locale : Locale.getAvailableLocales()) {
            ResourceBundle bundle = ResourceBundle.getBundle(LOCALIZATION_BUNDLE_BASE_NAME, locale);
            if (bundle != null && bundle.getLocale().equals(locale)) {
                availableBundles.put(locale, bundle);
            }
        }
        BUNDLES = Collections.unmodifiableMap(availableBundles);
        LOCALES = Collections.unmodifiableSet(BUNDLES.keySet());

        if (LOCALES.contains(Locale.getDefault())) {
            setLocale(Locale.getDefault());
        } else if (LOCALES.contains(Locale.US)) {
            setLocale(Locale.US);
        } else {
            setLocale(LOCALES.iterator().next());
        }
    }

    public static ResourceBundle getResourceBundle() {
        return getResourceBundle(locale);
    }

    @SuppressWarnings("WeakerAccess")
    public static ResourceBundle getResourceBundle(Locale locale) {
        return BUNDLES.get(locale);
    }

    public static String getString(String key) {
        return getString(key, locale);
    }

    @SuppressWarnings("WeakerAccess")
    public static String getString(String key, Locale locale) {
        try {
            return getResourceBundle(locale).getString(key);
        } catch (MissingResourceException e) {
            return "<" + key + ">";
        }
    }

    public static Locale getLocale() {
        return locale;
    }

    public static void setLocale(Locale newLocale) {
        if (LOCALES.contains(newLocale)) {
            LocalizationUtil.locale = newLocale;
            Locale.setDefault(newLocale);
        }
    }

    public static Locale getLocaleByName(String localeName) {

        Locale locale = LocaleUtils.toLocale(localeName);
        if (LOCALES.contains(locale)) {
            return locale;
        }

        return LocalizationUtil.locale;
    }
}
